﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using System.Data;

namespace SQLWrapper
{
    public class MySQLOperationManager
    {
        public static Task doSQLOperationAsync(Action<MySqlCommand> operation,Action<string> errHandler,CommandType type,bool needTransaction)
        {
            return Task.Factory.StartNew(() =>
                {
                    doSQLOperation(operation, errHandler, type, needTransaction);
                });
        }
        public static void doSQLOperation(Action<MySqlCommand> operation,Action<string> errHandler,CommandType type,bool needTransaction)
        {
            try
            {
                if (needTransaction)
                {
                    using (MySqlConnection conn = MySQLConnectionManager.getConnByDefaultConnectionString())
                    {
                        using (MySqlTransaction trans = conn.BeginTransaction())
                        {
                            using (MySqlCommand cmd = conn.CreateCommand())
                            {
                                cmd.CommandType = type;
                                cmd.Transaction = trans;
                                operation(cmd);
                            }
                            try
                            {
                                trans.Commit();
                            }
                            catch(Exception e)
                            {
                                trans.Rollback();
                                throw e;
                            }
                        }
                    }
                }
                else
                {
                    using (MySqlConnection conn = MySQLConnectionManager.getConnByDefaultConnectionString())
                    {
                        using (MySqlCommand cmd = conn.CreateCommand())
                        {
                            cmd.CommandType = type;
                            operation(cmd);
                        }
                    }
                }
            }
            catch(Exception ex)
            {
                errHandler(ex.Message);
            }
        }
        public static Task doSQLOperationWithLoadedDataAsync(Action<MySqlCommand> commandOP,Action<string> errHandler,Action<List<Dictionary<string,object>>> data,CommandType type,bool needTransaction)
        {
            return Task.Factory.StartNew(() =>
            {
                doSQLOperationWithLoadedData(commandOP, errHandler, data, type, needTransaction);
            });
        }
        public static void doSQLOperationWithLoadedData(Action<MySqlCommand> commandOP,Action<string> errHandler,Action<List<Dictionary<string,object>>> data,CommandType type,bool needTransaction)
        {
            try
            {
                if (needTransaction)
                {
                    using (MySqlConnection conn = MySQLConnectionManager.getConnByDefaultConnectionString())
                    {
                        using (MySqlTransaction trans = conn.BeginTransaction())
                        {
                            using (MySqlCommand cmd = conn.CreateCommand())
                            {
                                cmd.CommandType = type;
                                cmd.Transaction = trans;
                                commandOP(cmd);
                                List<Dictionary<string, object>> result = new List<Dictionary<string, object>>();
                                using (MySqlDataReader dr = cmd.ExecuteReader())
                                {
                                    while (dr.Read())
                                    {
                                        Dictionary<string, object> r = new Dictionary<string, object>();
                                        for (int i = 0; i < dr.FieldCount; i++)
                                        {
                                            r.Add(dr.GetName(i), dr[i].ToString());
                                        }
                                        result.Add(r);
                                    }
                                }
                                data(result);
                            }
                            try
                            {
                                trans.Commit();
                            }
                            catch (Exception e)
                            {
                                trans.Rollback();
                                throw e;
                            }
                        }
                    }
                }
                else
                {
                    using (MySqlConnection conn = MySQLConnectionManager.getConnByDefaultConnectionString())
                    {
                        using (MySqlCommand cmd = conn.CreateCommand())
                        {
                            cmd.CommandType = type;
                            commandOP(cmd);
                            List<Dictionary<string, object>> result = new List<Dictionary<string, object>>();
                            using (MySqlDataReader dr = cmd.ExecuteReader())
                            {
                                while (dr.Read())
                                {
                                    Dictionary<string, object> r = new Dictionary<string, object>();
                                    for (int i = 0; i < dr.FieldCount; i++)
                                    {
                                        r.Add(dr.GetName(i), dr[i]);
                                    }
                                    result.Add(r);
                                }
                            }
                            data(result);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                errHandler(ex.Message);
            }
        }
    }
}
